Scraping Tools
November 2, 2026
5 min

How to scrape LinkedIn public data with proxies (2026 guide)

Alex Sadovskij
Alex Sadovskij
CEO Proxy-Cheap
How to scrape LinkedIn public data with proxies (2026 guide)
Короткий зміст
Collect public LinkedIn profiles, company pages, and job data with Python, and match the right proxy type to each surface.

Web scraping LinkedIn means collecting the public data LinkedIn serves to logged-out visitors: profiles, company pages, job posts, and job search results. LinkedIn serves those surfaces to a point, then asks for a sign-in once one address requests too much too fast. Reliable collection at volume depends on the right proxy type and sensible request pacing, with a clear view of LinkedIn's terms and the law that applies to you.

Key takeaways

  • LinkedIn serves profiles, company pages, and public job data to logged-out visitors, up to a per-session volume. People search asks for a sign-in.
  • Match the proxy type to the surface. Datacenter, ISP, and unlimited bandwidth proxies suit high-volume public job data. Rotating residential and mobile proxies suit profiles and company pages at scale.
  • LinkedIn doesn't publish a request rate for logged-out visitors, so pace requests and treat a sign-in redirect or an HTTP 429 response as your signal to slow down.
  • Public-data collection sits in a nuanced legal position. hiQ v. LinkedIn addressed the CFAA, but LinkedIn's terms, copyright, and data-protection law such as GDPR still apply.

Which proxy type fits each LinkedIn surface

The right proxy depends on the LinkedIn surface. Public job pages and job search answer logged-out requests readily, so datacenter, ISP, and unlimited bandwidth proxies deliver the throughput they need. Public profiles and company pages are rate-limited per session, so rotating residential proxies that route through real consumer networks in your target markets fit collection at scale. For the highest-volume, longest-running jobs, rotating mobile proxies add the widest IP diversity.

Most guides on this topic skip the proxy question, because they sell a finished scraper with the proxy layer hidden inside. If you build your own collector, it's the first decision you make, and it shapes your success rate as much as your bill.

LinkedIn surfaceAccess behaviourRecommended proxy typeWhy it fits
Public job pages and job searchAnswers logged-out requests readilyDatacenter IPv4, ISP, or unlimited bandwidthHigh throughput and stable sessions for large volumes of job data
Public profilesServed logged-out up to a per-session volume, then a sign-in promptRotating residentialA fresh consumer IP per request or session, in the market you collect from
Company pagesOverview served logged-out; employee lists need a sign-inRotating residentialSame per-session pattern as profiles, so the same rotation logic fits
High-volume sustained collectionLong runs across many surfaces and marketsRotating mobileCarrier networks with broad IP diversity for the largest jobs
Fixed-IP or allowlist needOne stable address over days or weeksStatic residential (ISP)Fixed residential IPs with long session continuity
  • Public job pages and job search. These are the most open surfaces on LinkedIn. Throughput matters more than IP origin here, so dedicated datacenter IPs, ISP proxies, or unmetered SOCKS5 lines give a daily job crawl the speed and predictable per-IP cost it needs.
  • Public profiles and company pages. Here the per-session volume is what counts. A logged-out browser usually meets a sign-in prompt after a handful of profile views from one address. Rotating residential proxies spread that volume across many consumer IPs in 180+ locations, so each address stays at a normal browsing pace.
  • Sustained, very high volume. When a job runs for days across many markets, IP diversity becomes the main lever. Rotating mobile proxies route through carrier networks in 100+ countries, where many real users share each address.
  • Fixed-IP needs. A server-side job that authenticates by IP allowlist needs the same address every time. Static residential (ISP) proxies give you a fixed residential IP for the whole subscription.

Cost is the other half of the decision. Most buyers think in cost per 1,000 successful requests, and that's the right lens. At Proxy-Cheap, rotating residential and rotating mobile are billed per GB with no monthly commitment, so you can test one surface with a small top-up before you commit to a plan.

How to set up proxies for LinkedIn data collection

Setup has three choices: proxy type, session mode, and pacing. Pick the proxy type for your surface, then choose rotating sessions for broad coverage or sticky sessions when a task needs the same IP for several requests. Authenticate by username and password or by IP allowlist, and pace requests to sit within normal browsing volumes so sessions stay stable.

Generate your credentials in the Proxy-Cheap dashboard first. Each proxy comes with a host and port plus login details. If you're new to the options, our guide to proxy types explains the differences in more depth.

Here's a minimal Python setup with httpx, tested on version 0.28.1:

python import httpx PROXY = "http://USERNAME:PASSWORD@HOST:PORT"  # copy from your Proxy-Cheap dashboard HEADERS = {    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "                  "(KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36",    "Accept-Language": "en-US,en;q=0.9", } with httpx.Client(proxy=PROXY, headers=HEADERS, timeout=20) as client:    r = client.get(        "https://www.linkedin.com/jobs/search",        params={"keywords": "data engineer", "location": "Germany"},    )    print(r.status_code)  # 200

If you prefer requests, pass proxies={"http": PROXY, "https": PROXY} to requests.get() instead. For a SOCKS5 line, install httpx[socks] and start the proxy URL with socks5://.

The same request in cURL is a quick way to check credentials from the terminal:

bash curl -x "http://HOST:PORT" -U "USERNAME:PASSWORD" \  "https://www.linkedin.com/jobs/search?keywords=data%20engineer&location=Germany" \  -o jobs.html -w "%{http_code}\n"

A 200 means the proxy and the page both answered. A 407 means the proxy rejected your login details.

Rotating vs sticky sessions and rotation intervals

A rotating session gives you a new IP on every request, which suits breadth, like a list of 5,000 job URLs. A sticky session keeps one IP for a while, for tasks that need several requests in a row from the same address, such as reading a profile and then its public activity. In the Proxy-Cheap credentials generator, "Random IP" rotates per request and "Session IP" holds one address for about 30 minutes.

Authentication: username and password vs IP allowlist

Rotating residential proxies authenticate with a username and password only. Static residential and datacenter proxies support both, so you can allowlist your server's IP and keep credentials out of your code. If you manage proxies in the browser instead of a script, the Chrome proxy extension handles switching and rotation in a couple of clicks. To create proxies or rotate IPs from code, see the Proxy-Cheap API documentation.

Pacing requests within LinkedIn's limits

LinkedIn doesn't publish a request rate for logged-out visitors, so you read the limit from its responses. A redirect to a sign-in page or an HTTP 429 (too many requests) means you've gone past it, and the right move is to slow down. This helper waits a few seconds between pages and stops cleanly when LinkedIn asks for a pause:

python import random import time def fetch(client, url, params=None):    """Return the response, or None when LinkedIn asks you to slow down or sign in."""    r = client.get(url, params=params)    if r.status_code == 429 or "authwall" in r.headers.get("location", ""):        return None    time.sleep(random.uniform(3, 7))  # a few seconds between pages    return r

httpx doesn't follow redirects by default, so the sign-in redirect shows up in the Location header where you can see it. Log every None, back off, and resume later at a lower rate.

What public LinkedIn data you can collect

Public LinkedIn surfaces expose a defined set of fields. Profiles show name, location, current role and organization, and education. Company pages add industry, headcount, headquarters, and specialties. Public job pages and job search show title, company, location, posting date, employment type, and description. None include private contact details or member-only analytics, which require a sign-in.

Coverage on profiles varies from person to person, because members choose how much of their profile is public. Company pages also list the company type and founding year, while the employee list asks for a sign-in. A single job posting adds seniority level to the card fields.

Job search cards cover most hiring-trend work, so job data is the usual starting point. If your project feeds a market research pipeline, job cards alone can track hiring by role and city over time.

Some data is never public. Contact details, connection lists, and profile view counts all sit behind a login. People search asks for a sign-in even for logged-out visitors, so it falls outside public collection. For a wider look at the workload side, see our web data collection use case.

How LinkedIn serves public data

LinkedIn delivers public fields three ways. Some fields sit in the server-rendered HTML and can be read from the response directly. Others load inside script tags as JSON-LD, so the parser reads that script tag. Job search and company job lists come from a guest background endpoint that returns results in pages as you scroll.

Server-rendered HTML

Job search result cards and company overview sections arrive as plain HTML in the first response. You read them with CSS selectors or XPath. This parser pulls job cards with BeautifulSoup and lxml:

python from bs4 import BeautifulSoup def parse_cards(markup):    soup = BeautifulSoup(markup, "lxml")    jobs = []    for card in soup.select("div.base-card"):        def text(selector):            node = card.select_one(selector)            return node.get_text(strip=True) if node else None        link = card.select_one("a.base-card__full-link")        posted = card.select_one("time")        jobs.append({            "title": text("h3.base-search-card__title"),            "company": text("h4.base-search-card__subtitle"),            "location": text("span.job-search-card__location"),            "posted": posted["datetime"] if posted else None,            "url": link["href"].split("?")[0] if link else None,        })    return jobs

JSON-LD in script tags

Most public pages also carry structured data in JSON-LD, the W3C format for linked data. Load each application/ld+json script tag as JSON, then pick the item you need by its @type. Profiles use Person, company pages use Organization, and job pages use JobPosting.

python import json from bs4 import BeautifulSoup def read_json_ld(markup):    soup = BeautifulSoup(markup, "lxml")    items = []    for tag in soup.select('script[type="application/ld+json"]'):        data = json.loads(tag.string)        items.extend(data.get("@graph", [data]))  # profiles nest items in @graph    return items job = next(i for i in read_json_ld(r.text) if i.get("@type") == "JobPosting") print(job["title"], job["datePosted"], job["employmentType"])

The job description field is HTML-encoded, so run it through html.unescape() and BeautifulSoup to get clean text. JSON-LD tends to outlast CSS class names, because it follows the public schema.org vocabulary rather than LinkedIn's own markup.

Guest XHR endpoints

When you scroll a logged-out job search, the page calls a guest endpoint for the next batch: https://www.linkedin.com/jobs-guest/jobs/api/seeMoreJobPostings/search. It takes keywords, location, and a start offset, and returns job cards as HTML fragments. You can spot calls like this yourself by scrolling the page in a headless browser while you watch its network activity. Then call the endpoint directly:

python GUEST_SEARCH = "https://www.linkedin.com/jobs-guest/jobs/api/seeMoreJobPostings/search" all_jobs, start = [], 0 with httpx.Client(proxy=PROXY, headers=HEADERS, timeout=20) as client:    while start < 100:        r = fetch(client, GUEST_SEARCH,                  {"keywords": "data engineer", "location": "Germany", "start": start})        if r is None:            break  # LinkedIn asked for a pause, so resume later        batch = parse_cards(r.text)        if not batch:            break        all_jobs.extend(batch)        start += len(batch) print(len(all_jobs))

The loop steps start based on how many cards come back, so it doesn't depend on a fixed page size. Selectors and endpoints change without notice, so re-test your parser before each run. A parser that silently returns empty fields does more damage than one that fails loudly. To manage proxies through code as well, read our explainer on the proxy API.

Is scraping LinkedIn allowed? Terms, hiQ v. LinkedIn, and GDPR

Collecting public LinkedIn data sits in a nuanced legal position. In hiQ Labs v. LinkedIn, the Ninth Circuit found that reading public pages does not by itself breach the Computer Fraud and Abuse Act. That ruling did not make every project lawful: LinkedIn's User Agreement still forbids automated collection, and copyright, contract, and data-protection law such as GDPR apply. Collect only public data, honor the terms and applicable law, and consult a lawyer for your case.

The case is often quoted as blanket permission, so the details matter. hiQ Labs v. LinkedIn started in 2017, after LinkedIn sent hiQ a cease-and-desist letter over its collection of public profiles. In 2019, and again in April 2022 after the Supreme Court's Van Buren decision, the Ninth Circuit held that scraping publicly accessible data likely isn't access "without authorization" under the CFAA. Both rulings came at the preliminary injunction stage.

The case didn't end there. In November 2022, the district court found that hiQ had breached LinkedIn's User Agreement through automated collection and through contractors who created fake profiles. The parties settled that December with a consent judgment. hiQ paid $500,000, agreed to stop collecting LinkedIn data, and had to delete the data and code built from it.

What hiQ v. LinkedIn settledWhat it did not settle
Reading public pages likely isn't "without authorization" under the CFAA (Ninth Circuit)Whether collection is allowed under LinkedIn's contract terms
A site owner's objection alone doesn't make public pages off-limits under the CFAACopyright, data-protection, and privacy claims
 Rules outside the US, including GDPR

The contract question is the live one. The LinkedIn User Agreement (section 8.2) says members must not develop, support, or use software, scripts, robots, or other means to scrape or copy the Services, including profiles and other data. LinkedIn's robots.txt carries a similar notice about automated access. That exposure is separate from the CFAA question, and it applies most clearly when you hold a LinkedIn account, because that's when you've agreed to the terms.

Data protection is the other half. Under GDPR, a name tied to a job title is personal data, even when it's public. If you collect data on people in the EU, you need a lawful basis (usually legitimate interest, backed by a written assessment), and you should collect only the fields your purpose needs. Job and company data carry far less risk than profile data, which is one more reason many teams start there.

Proxy-Cheap's own appropriate use policy applies to every workload on our network. This section is general information, not legal advice, so talk to a lawyer about your specific project before collecting personal data.

Common reasons LinkedIn collection stalls, and how reliable proxies help

Public collection usually stalls for three reasons. A single address that requests too many pages too fast triggers a sign-in prompt. Requests from datacenter ranges used for hosting can be treated differently from consumer traffic. And running one long session without variation raises failure rates. Reliable residential and mobile proxies, with sensible pacing and rotation, address all three while keeping your request rate modest.

  • Request volume from one address. This is the complaint you'll see most in community threads: a script reads a few profiles, then every response turns into a sign-in page. LinkedIn limits logged-out views per visitor, and one IP running at script speed uses up that allowance in minutes. Rotate IPs so each address carries a normal share, and keep a few seconds between requests.
  • IP source and quality. Profile and company surfaces treat address ranges registered to hosting companies differently from consumer traffic. Residential proxies route requests through real consumer networks, which is the traffic those surfaces are built to serve. Keep datacenter and ISP lines on job data, where their throughput pays off. Match the exit country to the market you're studying, too, using our proxy locations list.
  • One long, unvaried session. A session that runs for hours at an even rhythm fails more often. Use sticky sessions only for the stretches that need one address, then rotate between tasks. The random delay in the fetch() helper keeps the pace uneven, the way real browsing is.

Tools and libraries for LinkedIn data collection

You can collect public LinkedIn data with open-source libraries, the official API, or no-code workflows. Python libraries such as requests, httpx, and BeautifulSoup handle fetching and parsing. Open-source repositories on GitHub package profile and job logic. LinkedIn's official API covers approved partner use cases. Whichever route you pick, the proxy layer underneath keeps collection reliable at volume.

  • Open-source Python. The stack in this guide (httpx or requests for fetching, BeautifulSoup with lxml for parsing) handles every public surface, and you control each request. For JavaScript-heavy pages, a headless browser such as Playwright renders the page first. joeyism/linkedin_scraper is a popular ready-made repository. Version 3 runs on Playwright and returns structured objects for each surface, but it signs in with a LinkedIn session, which brings the User Agreement exposure covered above.
  • The official LinkedIn API. This is the sanctioned route, but most of it sits behind partner programs. Self-serve access covers Sign In with LinkedIn and posting on a member's behalf. Business APIs, such as marketing and sales, require an approved partnership, so the API rarely fits open data collection.
  • No-code workflows. In n8n, an HTTP Request node (with a built-in proxy option) can feed an HTML extraction step, then a spreadsheet. Recruiting and growth teams use setups like this to track a fixed set of job searches without writing code.
RouteSkill levelControlBest for
Open-source PythonDeveloperFull control of requests and parsingCustom pipelines at volume
Official LinkedIn APIDeveloper plus partner approvalDefined by the partner programApproved product integrations
No-code (n8n and similar)OperatorModerateSmall, repeatable monitoring jobs

Every route needs the same proxy layer underneath. Datacenter proxies with dedicated IPv4 or IPv6 addresses handle daily job crawls at a predictable per-IP price, and IPv4 comes with a 7-day trial. ISP proxies come in static and rotating options for longer sessions. For very large job datasets, unlimited bandwidth proxies give you SOCKS5 access across 195+ locations with no data caps.

Ready to test a LinkedIn collection setup? Start with pay-as-you-go rotating residential or mobile proxies and run the scripts above on one surface. Measure your cost per 1,000 pages before you scale. There are no set-up costs, and you can cancel anytime.

Часті запитання

LinkedIn can suspend accounts it associates with automated collection, because its User Agreement forbids that activity. Collecting only public surfaces without a logged-in account keeps your account out of that exposure. If you must use an account, keep activity modest and expect suspension risk regardless.

Web scraping is not illegal by default. Courts have found that reading publicly available pages does not by itself breach the US Computer Fraud and Abuse Act. Liability depends on how you do it and what you collect: terms of service, copyright, contract, and data-protection laws such as GDPR still apply.

Yes, for public surfaces. Public profiles, company pages, and public job data answer logged-out requests up to a per-session volume. People search asks for a sign-in even for logged-out visitors, so it sits outside public collection.

AI tools can read and structure a page you already fetched, but they don't solve the collection layer. You still need proxies, pacing, and session handling to reach public LinkedIn pages reliably at volume. The AI step helps with parsing and enrichment, not with fetching.

It depends on the surface. Public job pages and job search often work with datacenter or ISP proxies because they answer logged-out requests readily. Public profiles and company pages at volume are better served by rotating residential or mobile proxies that route through real consumer networks.

Logged-out profile views typically meet a sign-in prompt after a handful of profiles from one address, and some guides put it at three to five. Rotating IPs and pacing requests raise how much you can collect while keeping each address at a modest rate. Treat any figure as a starting point and test the volume you plan to run.

Yes, LinkedIn offers an official API, but access runs through partner agreements and approved use cases, so most developers can't use it for open data collection. For public data outside those programs, collecting the public surfaces is the practical route. Confirm your use case against LinkedIn's developer terms.

Match the proxy type to the surface, rotate IPs, use sticky sessions where a task needs one address, and pace requests to sit within normal browsing volumes. Pay-as-you-go residential and mobile proxies let you test the approach before committing to a plan.